package com.okbihuo.perm.core.mp.base;

import cn.hutool.json.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.okbihuo.perm.core.mp.base.MyBaseModel;
import com.okbihuo.perm.core.mp.base.MyQueryCriteria;
import com.okbihuo.perm.core.mp.base.MyService;
import com.okbihuo.perm.core.tool.api.BaseException;
import com.okbihuo.perm.core.tool.api.R;
import com.okbihuo.perm.core.tool.api.ResultCode;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.WebUtils;

/**
 * @author Jr.November
 */
@SuppressWarnings("rawtypes")
public abstract class MyController<T extends MyBaseModel> {

    protected abstract MyService<T> getService();

    /**
     * 默认通过分页查询方法
     * @param query 分页条件
     */
    @GetMapping(value = {"page", ""})
    @ResponseBody
    public String listByPage(Page query, MyQueryCriteria criteria) {
        IPage page = afterListByPage(list(query, criteria));
        return R.data(page).toJSON();
    }

    /**
     * 自定义列表查询结果
     */
    protected IPage afterListByPage(IPage page) {
        return page;
    }

    /**
     * list核心方法
     * @param page 分页信息
     * @return 分页结果
     */
    protected IPage<T> list(IPage<T> page, MyQueryCriteria<T> criteria) {
        // beforePage 可以被继承替换
        this.beforePage(page);
        return getService().page(page, criteria);
    }

    /**
     * 可以被替换，实现自定获取filter的方法
     */
    protected void beforePage(IPage page) {
    }

    /**
     * 默认保存修改方法
     */
    @PostMapping(value = {"save"})
    @ResponseBody
    public String save(@RequestBody T entity) throws BaseException {
        entity.setVersion(null);
        T t = beforeSave(entity);
        T saved = getService().saveOrUpdateAndReturn(t);
        return R.data(saved).toJSON();
    }



    /**
     * 保存之前的操作, 可以被替换，实现自定义方法
     */
    protected T beforeSave(T entity) {
        return entity;
    }

    /**
     * 通过id获取实体
     *
     * @param id 主键
     * @return 有数据时返回实体
     */
    @GetMapping("get")
    @ResponseBody
    public String getById(Integer id) {
        T entity = getService().getById(id);
        Object o = afterGetById(entity);
        return R.data(o).toJSON();
    }

    /**
     * 通过id获取实体
     * @param id 主键
     * @return 有数据时返回实体
     */
    @GetMapping("{id}")
    @ResponseBody
    public String getBy(@PathVariable(name = "id") Integer id) {
        T entity = getService().getById(id);
        return  R.data(afterGetById(entity)).toJSON();
    }

    /**
     * 获取实体之后
     */
    protected Object afterGetById(T entity) {
        return entity;
    }

    /**
     * 通过id删除实体
     */
    @PostMapping({"remove"})
    @ResponseBody
    public String delete(Integer id) throws BaseException {
        if(id == null){
            throw new BaseException(ResultCode.PARAM_MISS, "缺少ID参数");
        }
        boolean b = this.getService().removeById(this.beforeDelete(id));
        if(b) {
            return R.data(id).toJSON();
        }else {
            throw  new BaseException(ResultCode.INTERNAL_SERVER_ERROR, "删除失败");
        }
    }

    /**
     * 删除之前的操作
     */
    protected int beforeDelete(Integer id) {
        return id;
    }

    /**
     * 修改生效/失效状态
     * @param id 实体id
     * @param disabled 1 失效 0 生效
     */
    @PostMapping("disable")
    @ResponseBody
    public String disable(Integer id, Integer disabled) throws BaseException {
        if(id == null){
            throw new BaseException(ResultCode.PARAM_MISS, "缺少ID参数");
        }
        if(disabled != 0 && disabled !=1) {
            throw new BaseException(ResultCode.PARAM_VALID_ERROR, "状态值不是0或1");
        }
        T updated = getService().update(id, "disabled", disabled);
        return R.data(updated).toJSON();
    }
}
